
#include "physicalconnector.hpp"
#include "stringlogger.hpp"
#include "message.h"


char SYNCPATTERN[] = {0x55,0x55}; //UU
unsigned int SYNCHRONIZATION_TIMEOUT = 2000;
unsigned int MSG_TIMEOUT = 1000;//not sure TODO:check in spec

namespace Connectors{
PhysicalConnector::PhysicalConnector(SerialPortConnector* serialConnector, const PartiesAddresses& parties,const Message& pingPongMsg)
    : m_addresses(parties), m_connector(serialConnector), m_ping(pingPongMsg), m_connState(DISCONNECTED)
{

}
std::vector<Message> PhysicalConnector::send(const Data& payload)
{
    Message masaz;
    std::vector<Message> retval;
    Data resp;
    masaz.setPayload(payload);
    masaz.addHeader();
    masaz.setAddresses(m_addresses);
    if(m_connector->send(masaz.getMsgBytes()))
        resp = m_connector->receive(MSG_TIMEOUT);
    try{
        m_buff.addBytes(resp);

        while(m_buff.isNextMessageInBuff())
        {
            retval.push_back(m_buff.getNextMessage());
        }

    }
    catch(const char* ex)
    {
        LOG << "Caught: " << ex << "\n";
    }
    return retval;

}
Message PhysicalConnector::send(const Message& msgToSend)
{
    throw "deprecated";
    return send(msgToSend.getPayload())[0];
}
void PhysicalConnector::startCommunication()
{
    /*
Request: 55 55
Answer:  55 55 D3 B0 (D3 = connection parameterxs bitset 7 bit of parameters and 1 parity bit)

Request: 4F       (~b0 = 4f)
Answer:  4F A7    (~a7 = 58) 58 is ecu's address
    */

    if(m_connState == DISCONNECTED)
    {
        LOG << (m_connector->connectPort(1) ? "Udalosie otworzyc port": "port sie nie otworzyl");

       Data response;
       m_connector->send(Data(SYNCPATTERN,SYNCPATTERN+2));
       response = m_connector->receive(SYNCHRONIZATION_TIMEOUT);
       if(response.size() < 4)
       {
           LOG << "response length incorrect\n";
           throw "response length incorrect";
       }
       //compare bytes
       if(response[0] != SYNCPATTERN[0] || response[1] != SYNCPATTERN[1])
       {
           LOG << "something went wrong as sync pattern wasn't returned correctly\n";
           throw "something went wrong as sync pattern wasn't returned correctly";
       }
       char firstKeyword = response[2];
       char secondKeyword = response[3];
       //get some data from first keyword here
       secondKeyword =  ~secondKeyword;
       m_connector->send(Data(&secondKeyword, &secondKeyword+1));
       response = m_connector->receive(SYNCHRONIZATION_TIMEOUT);
       if(response.size() < 2)
       {
           LOG << "response length incorrect\n";
           throw "response length incorrect";
       }
       if(response[0] != secondKeyword)
       {
           LOG << "something went wrong as 2nd sync pattern wasn't returned correctly\n";
//           throw "something went wrong as 2nd sync pattern wasn't returned correctly";
       }
       m_addresses.remoteParty = ~(response[1]);
       LOG << "Remote party address: " << std::hex << (int)(m_addresses.remoteParty) << "\n";
       m_connState = CONNECTED;
    }

}
void PhysicalConnector::stopCommunication()
{
    m_connState = DISCONNECTED;
}
}
